#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <wchar.h>
#include <sys/ioctl.h>
#include <ft2build.h>
#include <font_manager.h>


#include FT_FREETYPE_H
#include FT_GLYPH_H



static FT_Face  g_tFace;//对应字体文件
static int g_iDefaultFontSize = 12;

static int FreetypeGetStringRegionCar(char *str, PRegionCartesian ptRegionCar)
{
    int i;
    int error;
    FT_BBox bbox;
    FT_BBox glyph_bbox;
    FT_Vector pen;
    FT_Glyph  glyph;
    FT_GlyphSlot slot = g_tFace->glyph;

    /* 初始化 */
    bbox.xMin = bbox.yMin = 32000;
    bbox.xMax = bbox.yMax = -32000;

    /* 指定原点为(0, 0) */
    pen.x = 0;
    pen.y = 0;

    /* 计算每个字符的bounding box */
    /* 先translate, 再load char, 就可以得到它的外框了 */
    for (i = 0; i < strlen(str); i++)
    {
        /* 转换：transformation */
        FT_Set_Transform(g_tFace, 0, &pen);

        /* 加载位图: load glyph image into the slot (erase previous one) */
        error = FT_Load_Char(g_tFace, str[i], FT_LOAD_RENDER);
        if (error)
        {
            printf("FT_Load_Char error\n");
            return -1;
        }

        /* 取出glyph */
        error = FT_Get_Glyph(g_tFace->glyph, &glyph);
        if (error)
        {
            printf("FT_Get_Glyph error!\n");
            return -1;
        }
        
        /* 从glyph得到外框: bbox */
        FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &glyph_bbox);

        /* 更新外框 */
        if ( glyph_bbox.xMin < bbox.xMin )
            bbox.xMin = glyph_bbox.xMin;

        if ( glyph_bbox.yMin < bbox.yMin )
            bbox.yMin = glyph_bbox.yMin;

        if ( glyph_bbox.xMax > bbox.xMax )
            bbox.xMax = glyph_bbox.xMax;

        if ( glyph_bbox.yMax > bbox.yMax )
            bbox.yMax = glyph_bbox.yMax;
        
        /* 计算下一个字符的原点: increment pen position */
        pen.x += slot->advance.x;
        pen.y += slot->advance.y;
    }

    /* return string bbox */
    //*abbox = bbox;
    ptRegionCar->iLeftUpX = bbox.xMin;
    ptRegionCar->iLeftUpY = bbox.yMax;
    ptRegionCar->iWidth     = bbox.xMax - bbox.xMin + 1;
    ptRegionCar->iHeigh     = bbox.yMax - bbox.yMin + 1;

	return 0;	
}

static int FreeTypeFontInit(char *aFineName)
{
	FT_Library library;//对应freetype库
	int err;
	err=FT_Init_FreeType(&library);//初始化
	if(err)
	{
		printf("FT_Init_FreeType err\n");
		return -1;
	}
	err=FT_New_Face(library,aFineName,0,&g_tFace);//加载字体文件
	if(err)
	{
		printf("FT_New_Face err\n");
		return -1;
	}
	FT_Set_Pixel_Sizes(g_tFace,g_iDefaultFontSize,0);//设置默认字体大小
	return 0;
}
static int FreeTypeFontSize(int iFontSize)
{
	FT_Set_Pixel_Sizes(g_tFace,iFontSize,0);//设置字体大小
	return 0;
}
static int FreeTypeFontBitMap(unsigned char dwCode,PFontBitMap ptFontBitMap)
{
	int err;
	FT_Vector pen;//字符的原点(起笔点)
	//FT_Glyph  glyph;//对应的字符经过后的glyph即外形、轮廓
	FT_GlyphSlot slot=g_tFace->glyph;//对应字符的处理结果：含glyph和位图
	pen.x=ptFontBitMap->iCurOriginX*64;//单位：1/64像素
	pen.y=ptFontBitMap->iCurOriginY*64;//单位：1/64像素

	//转换（变形）
	FT_Set_Transform(g_tFace,0,&pen);

	//根据font_code加载字符，的搭配新的glyph和位图，结果保存再slot中
	err=FT_Load_Char(g_tFace,dwCode,FT_LOAD_RENDER);
	if(err)
	{
		printf("FT_load_Char err\n");
		return -1;
	}
	ptFontBitMap->pucBuffer  =slot->bitmap.buffer;
	ptFontBitMap->tRegion.iLeftUpX 	 =slot->bitmap_left;
	ptFontBitMap->tRegion.iLeftUpY	 =ptFontBitMap->iCurOriginY*2-slot->bitmap_top;
	ptFontBitMap->tRegion.iWidth	 =slot->bitmap.width;
	ptFontBitMap->tRegion.iHeigh	 	 =slot->bitmap.rows;
	ptFontBitMap->iNextOriginX=ptFontBitMap->iCurOriginX+slot->advance.x/64;//这里注意单位不一样所以要除以64
	ptFontBitMap->iNextOriginY=ptFontBitMap->iCurOriginY;//在同一行上绘制的所以y值应该保持不变
	return 0;
}

static  FontOpr g_tFreetypeOpr={
	.name			="freetype",//用free type还是用其他的
	.FontInit		=FreeTypeFontInit,//初始化
	.SetFontSize	=FreeTypeFontSize,//设置大小
	.GetFontBitMap	=FreeTypeFontBitMap,//获得字库
	.GetStringRegionCar=FreetypeGetStringRegionCar,
};

void FreetypeRegister(void)
{
	RegisterFont(&g_tFreetypeOpr);
}
